#include "Archiver.h"

Archiver::Archiver()
	: m_nCap(0)
{
	m_data = m_curr = NULL;
}

Archiver::~Archiver()
{
	if(m_data)
	{
		delete [] m_data;
	}
	m_data = m_curr = NULL;
	m_nCap = 0;
}

bool Archiver::PushValue(void* ptr, size_t nSize)
{
	if(MakeBuffer(nSize))
	{
		memcpy(m_curr, ptr, nSize);
		m_curr += nSize;
		return true;
	}
	return false;
}

bool Archiver::PopValue(void* ptr, size_t nSize)
{
	if(CheckBuffer(nSize))
	{
		memcpy(ptr, m_curr, nSize);
		m_curr += nSize;
		return true;
	}
	return false;
}

bool Archiver::MakeBuffer(size_t nSize)
{
	size_t nCurrSize = m_curr - m_data;
	size_t nCount = 0;
	nCount = (nCurrSize + nSize) / m_nCap;
	if( nCount > 0)
	{
		char *pBuf = new char[m_nCap + nCount * AllocSize];
		//assert(pBuf);
		if( !pBuf)
		{
			return false;
		}
		memcpy( pBuf, m_data, m_curr - m_data);
		nCurrSize += nSize;
		delete [] m_data;
		m_data = pBuf;
		m_curr = m_data + nCurrSize;
		return true;
	}
	return true;
}

bool Archiver::CheckBuffer(size_t nSize)
{
	if( ((m_curr - m_data) + nSize) > m_nCap)
	{
		return false;
	}
	return true;
}

size_t Archiver::length(void) const
{
	return m_curr - m_data;
}
